using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;

using Evaluant.Uss;
using Evaluant.Uss.Common;
using Evaluant.Uss.Commands;

namespace Evaluant.Uss.Trace
{
	/// <summary>
	/// Simple Delegate Engine implementation to show the interception capabilities of the framework
	/// </summary>
	public class TraceEngine : IPersistenceEngine
	{
        public TraceEngine(System.Globalization.CultureInfo culture)
		{
			_Culture = culture;
			_CommandProcessor = new TraceCommandProcessor();
		}

		ICommandProcessor _CommandProcessor;
		public ICommandProcessor CommandProcessor
		{
			get { return _CommandProcessor; }
			set { _CommandProcessor = value; }
		}

		private CultureInfo _Culture;
		public CultureInfo Culture
		{
			get { return _Culture; }
			set { _Culture = value;}
		}

		public EntitySet Load(string opath)
		{
			return Load(opath, new string[0]);
		}

		public EntitySet Load(string opath, string[] attributes)
		{
			return Load(opath, attributes, null, 1, 0);
		}

		public EntitySet Load(string opath, string orderby, int first, int max)
		{
			return Load(opath, new string[0], orderby, first, max);
		}

		public EntitySet LoadWithId(string type, string[] id)
		{
			return LoadWithId(type, id, new string[0]);
		}

		public Entity LoadWithId(string type, string id)
		{
			EntitySet result = LoadWithId(type, new string[] { id });
			return result.Count > 0 ? result[0] : null;
		}

		public void LoadReference(Entity entity)
		{
			LoadReference(new Entity[] { entity });
		}

		public void LoadReference(Entity entity, string[] references)
		{
			LoadReference(new Entity[] { entity }, references);
		}

		public void LoadReference(IEnumerable entities)
		{
			LoadReference(entities, new string[0]);
		}

		public void InitializeRepository()
		{
			System.Diagnostics.Trace.WriteLine("InitializeRepository");
		}

		public void Initialize()
		{
			System.Diagnostics.Trace.WriteLine("Initialize");
		}

		public EntitySet Load(string opath, string[] attributes, string orderby, int first, int max)
		{
			System.Diagnostics.Trace.WriteLine(String.Format("Load {0}", opath));
			return null;
		}

        public EntitySet Load(OPath.OPathQuery opath, string[] attributes, string orderby, int first, int max)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("Load {0}", opath.Path));
            return null;
        }

		public void LoadReference(System.Collections.IEnumerable entities, string[] references)
		{
			System.Diagnostics.Trace.WriteLine(String.Format("LoadReference {0}", String.Join("', '", references)));
		}

		public EntitySet LoadWithId(string type, string[] id, string[] attributes)
		{
			System.Diagnostics.Trace.WriteLine(String.Format("LoadWithId {0}", String.Join("', '", id)));
			return null;
		}

        public object LoadScalar(string opath)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("LoadScalar {0}", opath));
            return null;
        }
        
        public object LoadScalar(OPath.OPathQuery opath)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("LoadScalar {0}", opath.Expression));
            return null;
        }
		public void BeforeProcessCommands(Transaction tx)
		{
		}

		public void ProcessCommands(Transaction tx)
		{
			foreach(Command c in tx.PendingCommands)
				c.Accept(_CommandProcessor);
		}

		public void AfterProcessCommands(Transaction tx)
		{
		}

		public Evaluant.Uss.Models.Model Model
		{
			get { return null; }
		}

	}
}
